package com.mask.token.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Token监控服务
 * 提供Token使用统计和监控功能
 *
 * @author mask
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
@ConditionalOnProperty(name = "mask.token.monitor.enabled", havingValue = "true", matchIfMissing = false)
public class MaskTokenMonitorService {

    private final MaskTokenService tokenService;

    // 统计计数器
    private final AtomicLong totalTokenGenerated = new AtomicLong(0);
    private final AtomicLong totalTokenValidated = new AtomicLong(0);
    private final AtomicLong totalTokenRefreshed = new AtomicLong(0);
    private final AtomicLong totalTokenRevoked = new AtomicLong(0);
    private final AtomicLong totalLoginAttempts = new AtomicLong(0);
    private final AtomicLong totalLoginSuccess = new AtomicLong(0);
    private final AtomicLong totalLoginFailed = new AtomicLong(0);

    /**
     * 记录Token生成
     */
    public void recordTokenGenerated() {
        totalTokenGenerated.incrementAndGet();
        log.debug("Token生成统计: {}", totalTokenGenerated.get());
    }

    /**
     * 记录Token验证
     */
    public void recordTokenValidated() {
        totalTokenValidated.incrementAndGet();
        log.debug("Token验证统计: {}", totalTokenValidated.get());
    }

    /**
     * 记录Token刷新
     */
    public void recordTokenRefreshed() {
        totalTokenRefreshed.incrementAndGet();
        log.debug("Token刷新统计: {}", totalTokenRefreshed.get());
    }

    /**
     * 记录Token撤销
     */
    public void recordTokenRevoked() {
        totalTokenRevoked.incrementAndGet();
        log.debug("Token撤销统计: {}", totalTokenRevoked.get());
    }

    /**
     * 记录登录尝试
     */
    public void recordLoginAttempt() {
        totalLoginAttempts.incrementAndGet();
        log.debug("登录尝试统计: {}", totalLoginAttempts.get());
    }

    /**
     * 记录登录成功
     */
    public void recordLoginSuccess() {
        totalLoginSuccess.incrementAndGet();
        log.debug("登录成功统计: {}", totalLoginSuccess.get());
    }

    /**
     * 记录登录失败
     */
    public void recordLoginFailed() {
        totalLoginFailed.incrementAndGet();
        log.debug("登录失败统计: {}", totalLoginFailed.get());
    }

    /**
     * 获取Token统计信息
     */
    public TokenStatistics getTokenStatistics() {
        TokenStatistics stats = new TokenStatistics();
        stats.setTotalTokenGenerated(totalTokenGenerated.get());
        stats.setTotalTokenValidated(totalTokenValidated.get());
        stats.setTotalTokenRefreshed(totalTokenRefreshed.get());
        stats.setTotalTokenRevoked(totalTokenRevoked.get());
        stats.setTotalLoginAttempts(totalLoginAttempts.get());
        stats.setTotalLoginSuccess(totalLoginSuccess.get());
        stats.setTotalLoginFailed(totalLoginFailed.get());
        stats.setCurrentOnlineUsers(getCurrentOnlineUserCount());
        stats.setTimestamp(Instant.now());
        
        // 计算成功率
        if (totalLoginAttempts.get() > 0) {
            stats.setLoginSuccessRate((double) totalLoginSuccess.get() / totalLoginAttempts.get() * 100);
        }
        
        return stats;
    }

    /**
     * 获取当前在线用户数
     */
    private long getCurrentOnlineUserCount() {
        try {
            // 这里需要根据实际的Token存储方式来计算
            // 暂时返回0，实际实现需要遍历所有Token
            return 0;
        } catch (Exception e) {
            log.warn("获取在线用户数失败", e);
            return 0;
        }
    }

    /**
     * 重置统计信息
     */
    public void resetStatistics() {
        totalTokenGenerated.set(0);
        totalTokenValidated.set(0);
        totalTokenRefreshed.set(0);
        totalTokenRevoked.set(0);
        totalLoginAttempts.set(0);
        totalLoginSuccess.set(0);
        totalLoginFailed.set(0);
        log.info("Token统计信息已重置");
    }

    /**
     * Token统计信息
     */
    public static class TokenStatistics {
        private long totalTokenGenerated;
        private long totalTokenValidated;
        private long totalTokenRefreshed;
        private long totalTokenRevoked;
        private long totalLoginAttempts;
        private long totalLoginSuccess;
        private long totalLoginFailed;
        private long currentOnlineUsers;
        private double loginSuccessRate;
        private Instant timestamp;

        // Getters and Setters
        public long getTotalTokenGenerated() { return totalTokenGenerated; }
        public void setTotalTokenGenerated(long totalTokenGenerated) { this.totalTokenGenerated = totalTokenGenerated; }

        public long getTotalTokenValidated() { return totalTokenValidated; }
        public void setTotalTokenValidated(long totalTokenValidated) { this.totalTokenValidated = totalTokenValidated; }

        public long getTotalTokenRefreshed() { return totalTokenRefreshed; }
        public void setTotalTokenRefreshed(long totalTokenRefreshed) { this.totalTokenRefreshed = totalTokenRefreshed; }

        public long getTotalTokenRevoked() { return totalTokenRevoked; }
        public void setTotalTokenRevoked(long totalTokenRevoked) { this.totalTokenRevoked = totalTokenRevoked; }

        public long getTotalLoginAttempts() { return totalLoginAttempts; }
        public void setTotalLoginAttempts(long totalLoginAttempts) { this.totalLoginAttempts = totalLoginAttempts; }

        public long getTotalLoginSuccess() { return totalLoginSuccess; }
        public void setTotalLoginSuccess(long totalLoginSuccess) { this.totalLoginSuccess = totalLoginSuccess; }

        public long getTotalLoginFailed() { return totalLoginFailed; }
        public void setTotalLoginFailed(long totalLoginFailed) { this.totalLoginFailed = totalLoginFailed; }

        public long getCurrentOnlineUsers() { return currentOnlineUsers; }
        public void setCurrentOnlineUsers(long currentOnlineUsers) { this.currentOnlineUsers = currentOnlineUsers; }

        public double getLoginSuccessRate() { return loginSuccessRate; }
        public void setLoginSuccessRate(double loginSuccessRate) { this.loginSuccessRate = loginSuccessRate; }

        public Instant getTimestamp() { return timestamp; }
        public void setTimestamp(Instant timestamp) { this.timestamp = timestamp; }
    }
}
